package com.analysis.controller;

import com.analysis.dto.ApiResponse;
import com.analysis.dto.PageResponse;
import com.analysis.dto.ReferencesPageRequest;
import com.analysis.dto.WebTypeStatisticsRequest;
import com.analysis.entity.Project;
import com.analysis.entity.References;
import com.analysis.enums.RequireLogin;
import com.analysis.service.ProjectService;
import com.analysis.service.ReferencesService;
import com.analysis.utils.ExcelExportUtils;
import com.analysis.utils.UserUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

/**
 * 信源控制器
 */
@RestController
@RequestMapping("/api/references")
@CrossOrigin(origins = "*")
public class ReferencesController {

    @Autowired
    private ReferencesService referencesService;

    @Autowired
    private ProjectService projectService;

    /**
     * POST方式多条件分页查询信源（支持复杂查询条件）
     */
    @PostMapping("/page")
    @RequireLogin
    public ApiResponse<PageResponse<References>> searchReferencesByPage(@RequestBody ReferencesPageRequest request, HttpServletRequest httpRequest) {
        try {
            // 设置项目ID
            request.setProjectId(getProjectId(httpRequest));

            // 参数验证
            if (request.getPageNum() < 1) {
                request.setPageNum(1);
            }
            if (request.getPageSize() < 1 || request.getPageSize() > 100) {
                request.setPageSize(10);
            }
            // 执行分页查询
            PageResponse<References> pageResponse = referencesService.getReferencesByPageWithConditions(request);
            return ApiResponse.success(pageResponse);
        } catch (IllegalStateException e) {
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            return ApiResponse.error("搜索分页查询信源时发生错误: " + e.getMessage());
        }
    }


    /**
     * 创建信源
     */
    @PostMapping("/add")
    @RequireLogin
    public ApiResponse<References> createReferences(@RequestBody References references, HttpServletRequest request) {
        try {
            // 设置项目ID
            initProjectId(references, request);

            int result = referencesService.createReferences(references);
            if (result > 0) {
                return ApiResponse.success(references);
            } else {
                return ApiResponse.error("信源创建失败");
            }
        } catch (IllegalStateException e) {
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            return ApiResponse.error("创建信源时发生错误: " + e.getMessage());
        }
    }

    /**
     * 根据ID删除信源
     */
    @PostMapping("/delete")
    @RequireLogin
    public ApiResponse<String> deleteReferences(Long id, HttpServletRequest request) {
        try {
            Long projectId = getProjectId(request);
            References existReferences = referencesService.getReferencesById(id);
            if (existReferences == null || !existReferences.getProjectId().equals(projectId)) {
                return ApiResponse.error("信源不存在或无权限操作");
            }

            int result = referencesService.deleteReferences(id);
            if (result > 0) {
                return ApiResponse.success("信源删除成功");
            } else {
                return ApiResponse.error("信源不存在或删除失败");
            }
        } catch (IllegalStateException e) {
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            return ApiResponse.error("删除信源时发生错误: " + e.getMessage());
        }
    }

    /**
     * 更新信源信息
     */
    @PostMapping("/update")
    @RequireLogin
    public ApiResponse<References> updateReferences(@RequestBody References references, HttpServletRequest request) {
        try {
            initProjectId(references, request);

            References existReferences = referencesService.getReferencesById(references.getId());
            if (existReferences == null || !existReferences.getProjectId().equals(references.getProjectId())) {
                return ApiResponse.error("信源不存在或无权限操作");
            }

            int result = referencesService.updateReferences(references);
            if (result > 0) {
                return ApiResponse.success();
            } else {
                return ApiResponse.error("信源不存在或更新失败");
            }
        } catch (IllegalStateException e) {
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            return ApiResponse.error("更新信源时发生错误: " + e.getMessage());
        }
    }

    /**
     * 根据ID查询信源
     */
    @GetMapping("/get")
    @RequireLogin
    public ApiResponse<References> getReferencesById(Long id, HttpServletRequest request) {
        try {
            Long projectId = getProjectId(request);
            References references = referencesService.getReferencesById(id);
            if (references != null && references.getProjectId().equals(projectId)) {
                return ApiResponse.success(references);
            } else {
                return ApiResponse.error("信源不存在");
            }
        } catch (IllegalStateException e) {
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            return ApiResponse.error("查询信源时发生错误: " + e.getMessage());
        }
    }


    /**
     * 批量创建信源
     */
    @PostMapping("/batch/add")
    @RequireLogin
    public ApiResponse<String> batchCreateReferences(@RequestBody List<References> referencesList, HttpServletRequest request) {
        try {
            Long companyId = UserUtils.getCurrentUserOrThrow(request).getCompanyId();
            Project project = projectService.getSelectedByCompanyId(companyId);
            // 为所有信源设置当前用户ID
            for (References references : referencesList) {
                references.setProjectId(project.getId());
                references.setCompanyId(project.getCompanyId());
            }
            int count = referencesService.batchCreateReferences(referencesList);
            return ApiResponse.success("批量创建成功，共创建 " + count + " 个信源");
        } catch (IllegalStateException e) {
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            return ApiResponse.error("批量创建信源时发生错误: " + e.getMessage());
        }
    }

    /**
     * 导出信源数据到Excel
     *
     * @param request            查询请求参数
     * @param httpServletRequest HTTP请求对象
     * @return Excel文件响应
     */
    @PostMapping("/export/excel")
    @RequireLogin
    public ResponseEntity<byte[]> exportReferencesToExcel(@RequestBody ReferencesPageRequest request,
                                                          HttpServletRequest httpServletRequest) {
        try {
            request.setProjectId(getProjectId(httpServletRequest));

            // 导出Excel
            byte[] excelBytes = referencesService.exportReferencesToExcel(request);

            if (excelBytes.length == 0) {
                return ResponseEntity.status(HttpStatus.NO_CONTENT)
                        .body("No data to export".getBytes());
            }

            // 生成文件名
            String fileName = ExcelExportUtils.generateFileName("references_data");

            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

            // 正确处理中文文件名编码
            String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8)
                    .replaceAll("\\+", "%20");
            headers.set("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"; filename*=UTF-8''" + encodedFileName);
            headers.setContentLength(excelBytes.length);

            return ResponseEntity.ok()
                    .headers(headers)
                    .body(excelBytes);

        } catch (IllegalStateException e) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                    .body(("User not logged in or session expired: " + e.getMessage()).getBytes());
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(("Excel export failed: " + e.getMessage()).getBytes());
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(("Error exporting references data: " + e.getMessage()).getBytes());
        }
    }

    /**
     * GET方式导出信源数据到Excel（支持URL参数）
     *
     * @param request            查询请求参数
     * @param httpServletRequest HTTP请求对象
     * @return Excel文件响应
     */
    @GetMapping("/export/excel")
//    @RequireLogin
    public ResponseEntity<byte[]> exportReferencesToExcelGet(ReferencesPageRequest request,
                                                             HttpServletRequest httpServletRequest) {
        try {
            // 导出Excel
            byte[] excelBytes = referencesService.exportReferencesToExcel(request);

            if (excelBytes.length == 0) {
                return ResponseEntity.status(HttpStatus.NO_CONTENT)
                        .body("No data to export".getBytes());
            }

            // 生成文件名
            String fileName = ExcelExportUtils.generateFileName("references_data");

            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

            // 正确处理中文文件名编码
            String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8)
                    .replaceAll("\\+", "%20");
            headers.set("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"; filename*=UTF-8''" + encodedFileName);
            headers.setContentLength(excelBytes.length);

            return ResponseEntity.ok()
                    .headers(headers)
                    .body(excelBytes);

        } catch (IllegalStateException e) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                    .body(("User not logged in or session expired: " + e.getMessage()).getBytes());
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(("Excel export failed: " + e.getMessage()).getBytes());
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(("Error exporting references data: " + e.getMessage()).getBytes());
        }
    }

    /**
     * 批量更新web_type：根据product_name匹配product表，根据URL是否包含domain设置web_type
     * 1: 官网（URL包含domain）
     * 2: 其他（URL不包含domain或未找到匹配product）
     * 支持按条件筛选：ids、productName、userId、aiModel
     */
    @PostMapping("/sync/webType")
    @RequireLogin
    public ApiResponse<Map<String, Object>> batchUpdateWebTypeByProductMatch(@RequestBody WebTypeStatisticsRequest request, HttpServletRequest httpRequest) {
        try {
            Long projectId = getProjectId(httpRequest);

            // 执行批量更新
            Map<String, Object> result = referencesService.batchUpdateWebTypeByProductMatch(
                    request.getIds(),
                    request.getProductName(),
                    projectId,
                    request.getAiModel()
            );

            return ApiResponse.success(result);
        } catch (IllegalStateException e) {
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            return ApiResponse.error("批量更新web_type时发生错误: " + e.getMessage());
        }
    }

    /**
     * 分析网站类型
     * 返回webType=1和webType=2的总数
     * 支持按条件筛选：ids、productName、userId、aiModel
     */
    @PostMapping("/statistics/webtype")
    @RequireLogin
    public ApiResponse<Map<String, Object>> getWebTypeStatistics(@RequestBody WebTypeStatisticsRequest request, HttpServletRequest httpRequest) {
        try {
            Long projectId = getProjectId(httpRequest);

            // 获取统计信息
            Map<String, Object> statistics = referencesService.getWebTypeStatistics(
                    request.getIds(),
                    request.getProductName(),
                    projectId,
                    request.getAiModel()
            );

            return ApiResponse.success(statistics);
        } catch (IllegalStateException e) {
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            return ApiResponse.error("获取webType统计信息时发生错误: " + e.getMessage());
        }
    }

    /**
     * 导入Excel文件到References表
     * 支持数据去重，如果（url、product_name）已存在则过滤不保存
     * Excel文件应包含列：webName, url, productName, aiModel, question
     */
    @PostMapping("/import/excel")
    @RequireLogin
    public ApiResponse<Map<String, Object>> importReferencesFromExcelFile(
            @RequestParam("file") MultipartFile file,
            HttpServletRequest httpRequest) {
        try {
            // 验证文件
            if (file == null || file.isEmpty()) {
                return ApiResponse.error("请选择要上传的Excel文件");
            }

            // 验证文件类型
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null || (!originalFilename.endsWith(".xlsx") && !originalFilename.endsWith(".xls"))) {
                return ApiResponse.error("请上传Excel文件（.xlsx或.xls格式）");
            }

            // 获取当前选中的项目
            Long projectId = getProjectId(httpRequest);

            // 执行导入
            Map<String, Object> result = referencesService.importReferencesFromExcelFile(file, projectId);

            return ApiResponse.success(result);
        } catch (IllegalStateException e) {
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            return ApiResponse.error("导入Excel文件时发生错误: " + e.getMessage());
        }
    }

    public Long getProjectId(HttpServletRequest request) {
        Long companyId = UserUtils.getCurrentUserOrThrow(request).getCompanyId();
        Project project = projectService.getSelectedByCompanyId(companyId);
        if (project == null) {
            throw new IllegalStateException("项目不存在或无权限操作");
        }
        return project.getId();
    }

    public void initProjectId(References references, HttpServletRequest request) {
        Long companyId = UserUtils.getCurrentUserOrThrow(request).getCompanyId();
        Project project = projectService.getSelectedByCompanyId(companyId);
        if (project == null) {
            throw new IllegalStateException("项目不存在或无权限操作");
        }
        references.setProjectId(project.getId());
        references.setCompanyId(project.getCompanyId());
    }

}
